package com.cwh.taskcenter.system;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.alibaba.cola.exception.BizException;
import com.cwh.taskcenter.domain.system.domainservice.MailSendDomainService;
import com.cwh.taskcenter.domain.system.model.MailSendStatusEnum;
import com.cwh.taskcenter.notice.email.dto.MailSendMessageDTO;
import com.cwh.taskcenter.system.mapper.SystemMailAccountMapper;
import com.cwh.taskcenter.system.mapper.SystemMailLogMapper;
import com.cwh.taskcenter.system.model.SystemMailAccountDO;
import com.cwh.taskcenter.system.model.SystemMailLogDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

import static cn.hutool.core.exceptions.ExceptionUtil.getRootCauseMessage;

/**
 * @author cwh
 */
@Slf4j
@Service
public class MailSendDomainServiceImpl implements MailSendDomainService {

    @Autowired
    private SystemMailAccountMapper mailAccountMapper;

    @Autowired
    private SystemMailLogMapper mailLogMapper;


    @Override
    public void doSendMail(MailSendMessageDTO message) {
        // 1. 创建发送账号
        SystemMailAccountDO account = validateMailAccount(message.getAccountId());
        MailAccount mailAccount  = buildMailAccount(account, message.getNickname());
        SystemMailLogDO systemMailLogDO = buildMailLogDO(message,account);
        // 2. 发送邮件
        try {
            String messageId = MailUtil.send(mailAccount, message.getMail(),
                    message.getTitle(), message.getContent(), true);
            // 3. 更新结果（成功）
            systemMailLogDO.setSendMessageId(messageId);
            systemMailLogDO.setSendStatus(MailSendStatusEnum.SUCCESS.getStatus());
            mailLogMapper.create(systemMailLogDO);
        } catch (Exception e) {
            // 3. 更新结果（异常）
            systemMailLogDO.setSendException(getRootCauseMessage(e));
            systemMailLogDO.setSendStatus(MailSendStatusEnum.FAILURE.getStatus());
            mailLogMapper.create(systemMailLogDO);
        }
    }

    SystemMailAccountDO validateMailAccount(Long accountId) {
        // 获得邮箱账号。考虑到效率，从缓存中获取
        SystemMailAccountDO account = mailAccountMapper.findById(accountId);
        // 邮箱账号不存在
        if (account == null) {
            throw new BizException("MAIL_ACCOUNT_NOT_EXISTS");
        }
        return account;
    }

    private MailAccount buildMailAccount(SystemMailAccountDO account, String nickname) {
        String from = StrUtil.isNotEmpty(nickname) ? nickname + " <" + account.getMail() + ">" : account.getMail();
        return new MailAccount().setFrom(from).setAuth(true)
                .setUser(account.getUsername()).setPass(account.getPassword())
                .setHost(account.getHost()).setPort(account.getPort())
                .setSslEnable(account.getSslEnable()).setStarttlsEnable(account.getStarttlsEnable());
    }

    private SystemMailLogDO buildMailLogDO(MailSendMessageDTO message,SystemMailAccountDO account) {
        SystemMailLogDO log = new SystemMailLogDO();
        log.setId(message.getLogId());
        log.setUserId(message.getUserId());
        log.setToMail(message.getMail());
        log.setAccountId(message.getAccountId());
        log.setFromMail(account.getMail());
        log.setTemplateTitle(message.getTitle());
        log.setTemplateContent(message.getContent());
        log.setTemplateNickname(message.getNickname());
        log.setSendTime(LocalDateTime.now());
        return log;
    }
}
